﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CodeBuilder.Repository
{
    internal class CreateRepository
    {
        private string tableName;
        private string fileDir;
        private DataTable dataTable;
        private DataTable indexTable;
        public CreateRepository(string tableName, string fileDir, DataTable dataTable, DataTable indexTable)
        {
            this.tableName = tableName;
            this.fileDir = fileDir;
            this.dataTable = dataTable;
            this.indexTable = indexTable;
        }

        public void Run()
        {
            var dataRows = new List<DataRow>();
            foreach (DataRow row in this.dataTable.Rows)
            {
                dataRows.Add(row);
            }
            var formatTableName = Helper.GetPascalCase(tableName);
            var entityName = $"{formatTableName}Entity";
            var fileName = $"{formatTableName}Repository";
            IList<string> contents = new List<string>();
            contents.Add($"using Hualong.TestWorldPro.Entities;");
            contents.Add($"using Microsoft.Extensions.Logging;");
            contents.Add($"namespace Hualong.TestWorldPro.Repository.{formatTableName}");
            contents.Add("{");
            contents.Add($"    public partial class {formatTableName}Repository : BaseRepository, I{formatTableName}Repository");
            contents.Add("    {");
            contents.Add($"        public {fileName}(ILogger<{fileName}> logger) : base(logger)");
            contents.Add("        {");
            contents.Add($"            var result = SqliteDb.CreateTableAsync<{entityName}>().Result;");
            contents.Add("        }");
            var indexRows = new List<DataRow>();
            foreach (DataRow row in this.indexTable.Rows)
            {
                indexRows.Add(row);
            }
            var indexRowGroups = indexRows.GroupBy(xx => xx[2].ToString()).ToList();
            foreach (var indexRowGroup in indexRowGroups)
            {
                if (indexRowGroup.Count() == 1 && indexRowGroup.FirstOrDefault()[4].ToString() == "id")
                    continue;
                var rows = indexRowGroup.OrderBy(xx => xx[3]).ToList();
                string methodName = string.Empty;
                string parasName = string.Empty;
                string returnName = string.Empty;
                string filterName = string.Empty;
                string delFilterName = string.Empty;
                string filterCond = string.Empty;
                string complex = string.Empty;
                for (int i = 0; i < rows.Count; i++)
                {
                    DataRow field = dataRows.FirstOrDefault(xx => xx[0].ToString() == rows[i][4].ToString());
                    methodName += $"{Helper.GetPascalCase(rows[i][4].ToString())}";
                    parasName += $"{DataTypeMap.Get(field[1].ToString())} {Helper.GetCamelCase(rows[i][4].ToString())}";
                    filterCond += $"i.{Helper.GetPascalCase(rows[i][4].ToString())} == {Helper.GetCamelCase(rows[i][4].ToString())}";
                    if (i < rows.Count - 1)
                    {
                        methodName += "And";
                        parasName += ", ";
                        filterCond += " && ";
                    }
                }
                if (rows.FirstOrDefault()[1].ToString() == "0")
                {
                    returnName = $"Task<{entityName}>";
                    filterName = $"FirstOrDefaultAsync(i => {filterCond})";
                }
                else
                {
                    returnName = $"Task<IList<{entityName}>>";
                    filterName = $"Where(i => {filterCond}).ToListAsync()";
                    complex = "s";
                }
                contents.Add($"        public async {returnName} GetItem{complex}By{methodName}Async({parasName})");
                contents.Add("        {");
                contents.Add($"            return await SqliteDb.Table<{entityName}>().{filterName};");
                contents.Add("        }");
                //delete
                contents.Add($"        public async Task<int> Delete{complex}By{methodName}Async({parasName})");
                contents.Add("        {");
                contents.Add($"            return await SqliteDb.Table<{entityName}>().DeleteAsync(i => {filterCond});");
                contents.Add("        }");
            }
            contents.Add($"        public async Task<{entityName}> GetItemAsync(long id)");
            contents.Add("        {");
            contents.Add($"            return await SqliteDb.Table<{entityName}>().FirstOrDefaultAsync(i => i.Id == id);");
            contents.Add("        }");
            contents.Add($"        public async Task<IList<{entityName}>> GetItemsAsync()");
            contents.Add("        {");
            contents.Add($"            return await SqliteDb.Table<{entityName}>().ToListAsync();");
            contents.Add("        }");
            contents.Add("    }");
            contents.Add("}");
            string filePath = Path.Combine(fileDir, formatTableName);
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            filePath = Path.Combine(filePath, $"{fileName}.cs");
            if (File.Exists(filePath))
            { File.Delete(filePath); }
            File.WriteAllLines(filePath, contents, Encoding.UTF8);

            Console.WriteLine($"创建:{filePath} 完成！");
        }
    }
}
